package com.example.compreshensiveshop.service.imp;

import cn.hutool.core.util.IdUtil;
import com.example.compreshensiveshop.dao.OrdersDao;
import com.example.compreshensiveshop.dto.OrderCreateDTO;
import com.example.compreshensiveshop.dto.OrderItemDTO;
import com.example.compreshensiveshop.po.CustomerPO;
import com.example.compreshensiveshop.po.ItemPO;
import com.example.compreshensiveshop.po.OrdersPO;
import com.example.compreshensiveshop.po.SellerPO;
import com.example.compreshensiveshop.service.*;
import com.example.compreshensiveshop.vo.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qiniu.sms.model.TemplateInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Orders Service Implementation
 */
@Service
public class OrdersServiceImpl implements OrdersService {
    @Autowired
    private OrdersDao ordersDao;
    @Autowired
    private SkuService skuService;
    @Autowired
    private ItemService itemService;
    @Autowired
    private SellerService sellerService;
    @Autowired
    private ProductService productService;
    @Autowired
    private CustomerService customerService;
    @Override
    public OrderNumberVO getOrderNumber(Long customerId) {
        return ordersDao.getOrderNumber(customerId);
    }

    @Override
    public OrderCreateVO addOrder(OrderCreateDTO orderCreateDTO) {
        for(OrderItemDTO orderItemDTO:orderCreateDTO.getOrderItemDTOS()){
            skuService.checkStock(orderItemDTO.getSkuId(),orderItemDTO.getQuantity());
            skuService.lockStock(orderItemDTO.getSkuId(),orderItemDTO.getQuantity());
        }
        String productName = orderCreateDTO.getOrderItemDTOS().size() == 1
                ? orderCreateDTO.getOrderItemDTOS().get(0).getProductName()
                : orderCreateDTO.getOrderItemDTOS().get(0).getProductName() + "等" + orderCreateDTO.getOrderItemDTOS().size() + "件商品";
        Long orderId = IdUtil.getSnowflake().nextId();
        OrdersPO  ordersPO = OrdersPO.builder()
                .orderId(orderId)
                .customerId(orderCreateDTO.getCustomerId())
                .totalAmount(orderCreateDTO.getTotalPrice())
                .orderName(productName)
                .build();
        ordersDao.addOrder(ordersPO);
        for(OrderItemDTO orderItemDTO:orderCreateDTO.getOrderItemDTOS()){
            ItemPO itemPO = ItemPO.builder()
                    .ordersId(orderId)
                    .skuId(orderItemDTO.getSkuId())
                    .address(orderItemDTO.getAddress())
                    .productName( orderItemDTO.getProductName())
                    .quantity(orderItemDTO.getQuantity())
                    .productPrice(orderItemDTO.getPrice())
                    .sellerId(orderItemDTO.getSellerId())
                    .build();
            itemService.addItem(itemPO);
        }
        return OrderCreateVO.builder()
                .orderId(orderId)
                .totalPrice(orderCreateDTO.getTotalPrice())
                .productName(productName)
                .createTime(new Timestamp(System.currentTimeMillis()))
                .customerName(customerService.queryMessageById(orderCreateDTO.getCustomerId()))
                .build();

    }

    @Override
    public PageInfo<OrderCustomerVO> getCustomerOrder(Integer pageNum,Integer pageSize, Long customerId, Integer status) {
        int total = ordersDao.countCustomerOrder(customerId, status);
        int offset = (pageNum - 1) * pageSize;
        List<OrdersPO> ordersPOList = ordersDao.getCustomerOrder(customerId, status, offset, pageSize);
        List<OrderCustomerVO> orderCustomerVOS = new ArrayList<>();
        for(OrdersPO ordersPO : ordersPOList){
            List<ItemPO> itemPOList = itemService.queryByOId(ordersPO.getOrderId());
            Map<Long,List<ItemPO>> itemPOMap = itemPOList.stream().collect(Collectors.groupingBy(ItemPO::getSellerId));
            List<OrderCustomerBySeller> orderCustomerBySellerList = new ArrayList<>();
            for (Map.Entry<Long,List<ItemPO>> entry : itemPOMap.entrySet()){
                Long sellerId = entry.getKey();
                List<ItemPO> itemPOListBySeller = entry.getValue();
                OrderCustomerBySeller orderCustomerBySeller = buildSellerVO(sellerId, itemPOListBySeller);
                orderCustomerBySellerList.add(orderCustomerBySeller);
            }
            orderCustomerVOS.add(OrderCustomerVO.builder()
                    .orderId(ordersPO.getOrderId())
                    .totalPrice(ordersPO.getTotalAmount())
                    .createTime(ordersPO.getCreateTime())
                    .payTime(ordersPO.getPayTime())
                    .deliveryTime(ordersPO.getDeliveryTime())
                    .finishTime(ordersPO.getFinishTime())
                    .orderCustomerBySellers(orderCustomerBySellerList)
                    .orderName(ordersPO.getOrderName())
                    .status(ordersPO.getStatus())
                    .build()
            );
        }
        PageInfo<OrderCustomerVO> pageInfo = new PageInfo<>(orderCustomerVOS);
        pageInfo.setTotal(total);
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        pageInfo.setPages((int) Math.ceil((double) total / pageSize));
        // ... 其他分页属性

        return pageInfo;

    }

    @Override
    public PageInfo<OrderSellerList> getSellerOrder(Integer pageNum, Integer pageSize, Long sellerId, Integer status, String keyword, Integer itemStatus) {
        int total = itemService.countSellerOrderFilter(sellerId, status, keyword, itemStatus);
        // 2. 手动分页查询item
        int offset = (pageNum - 1) * pageSize;
        List<ItemPO> itemPOs = itemService.querySellerOrderFilter(sellerId, status, keyword, itemStatus, offset, pageSize);
       List<OrderSellerList> orderSellerLists = new ArrayList<>();
        for (ItemPO itemPO : itemPOs){
            OrdersPO ordersPO = ordersDao.queryById(itemPO.getOrdersId());
            CustomerPO customerPO = customerService.queryById(ordersPO.getCustomerId());
            orderSellerLists.add(OrderSellerList. builder ()
                    .orderId(ordersPO.getOrderId())
                    .status(ordersPO.getStatus())
                    .customerName(customerPO.getNickname())
                    .address(customerPO.getAddress())
                    .orderItemVO(buildItemVO(itemPO))
                    .createTime(ordersPO.getCreateTime())
                    .payTime(ordersPO.getPayTime())
                    .deliveryTime(ordersPO.getDeliveryTime())
                    .finishTime(ordersPO.getFinishTime())
                    .build()
            );
        }
        // 5. 手动构造PageInfo
        PageInfo<OrderSellerList> pageInfo = new PageInfo<>(orderSellerLists);
        pageInfo.setTotal(total);
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        pageInfo.setPages((int) Math.ceil((double) total / pageSize));
        // ... 其他分页属性

        return pageInfo;
    }

    @Override
    public List<Long> queryTimeoutOrders() {
        return ordersDao.queryTimeoutOrders();
    }

    @Override
    public void closeOrder(Long orderId) {
        ordersDao.closeOrder(orderId);
    }

    @Override
    public OrderCustomerVO queryOrderMessage(Long orderId) {
        OrdersPO ordersPO = ordersDao.queryById(orderId);
        List<ItemPO> itemPOList = itemService.queryByOId(orderId);
        Map<Long, List<ItemPO>> itemPOMap = itemPOList.stream().collect(Collectors.groupingBy(ItemPO::getSellerId));
        List<OrderCustomerBySeller> orderCustomerBySellerList = new ArrayList<>();
        for (Map.Entry<Long, List<ItemPO>> entry : itemPOMap.entrySet()) {
            Long sellerId = entry.getKey();
            List<ItemPO> itemPOListBySeller = entry.getValue();
            OrderCustomerBySeller orderCustomerBySeller = buildSellerVO(sellerId, itemPOListBySeller);
            orderCustomerBySellerList.add(orderCustomerBySeller);
        }
        return OrderCustomerVO.builder()
                .orderId(ordersPO.getOrderId())
                .totalPrice(ordersPO.getTotalAmount())
                .createTime(ordersPO.getCreateTime())
                .payTime(ordersPO.getPayTime())
                .deliveryTime(ordersPO.getDeliveryTime())
                .finishTime(ordersPO.getFinishTime())
                .orderCustomerBySellers(orderCustomerBySellerList)
                .orderName(ordersPO.getOrderName())
                .customerName(customerService.queryById(ordersPO.getCustomerId()).getNickname())
                .build();
    }

    @Override
    public List<DailySalesVO> queryDailySales(Long sellerId, Integer year, Integer month) {
        return itemService.queryDailySales(sellerId,year,month);
    }

    @Override
    public List<MonthlySalesVO> queryMonthLySales(Long sellerId, Integer year) {
        return itemService.queryMonthLySales(sellerId,year);
    }

    @Override
    public void updateOrderStatus(Long orderId, Integer status) {
         ordersDao.updateOrderStatus(orderId,status);
         List<ItemPO> itemPOs = itemService.queryByOId(orderId);
         if(status==4){
             for (ItemPO itemPO:itemPOs){
                 itemService.updateItemStatus(itemPO.getId(),2);
             }
         }
         if(status==5){
             for (ItemPO itemPO:itemPOs){
                 itemService.updateItemStatus(itemPO.getId(),3);
             }
         }
    }

    @Override
    public void deliverOrder(Long orderId,Long ItemId) {
        itemService.updateItemStatus(ItemId,1);
        List<ItemPO> itemPOs = itemService.queryByOId(orderId);
        int upStatus = 3;
        for(ItemPO itemPO:itemPOs){
            if(itemPO.getItemStatus()!=1){
             upStatus=2;
             break;
            }
        }
        ordersDao.updateOrderStatus(orderId,upStatus);

    }


    private OrderCustomerBySeller buildSellerVO(Long sellerId, List<ItemPO> itemPOListBySeller) {
        SellerPO sellerPO = sellerService.queryById(sellerId);
        BigDecimal totalPrice = itemPOListBySeller.stream()
                .map(itemPO -> itemPO.getProductPrice().multiply(new BigDecimal(itemPO.getQuantity())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        List<OrderItemVO> orderItemVOS = itemPOListBySeller.stream()
        .map(this::buildItemVO)
        .collect(Collectors.toList());
      return OrderCustomerBySeller.builder()
                .sellerId(sellerId)
                .sellerName(sellerPO.getShopName())
                .totalPrice(totalPrice)
                .orderItemVOList(orderItemVOS)
                .build();
    }

    private OrderItemVO buildItemVO(ItemPO itemPO) {
        return OrderItemVO.builder()
                .id(itemPO.getId())
                .skuId(itemPO.getSkuId())
                .productName(itemPO.getProductName())
                .productImage(productService.queryProductMainImage(itemPO.getSkuId()))
                .price(itemPO.getProductPrice())
                .quantity(itemPO.getQuantity())
                .totalPrice(itemPO.getProductPrice().multiply(new BigDecimal(itemPO.getQuantity())))
                .address(itemPO.getAddress())
                .skuName(productService.queryProductSkuName(itemPO.getSkuId()))
                .status(itemPO.getItemStatus())
                .build();
    }
}